from sklearn.feature_extraction.text import TfidfVectorizer  #原始文本转化为tf-idf的特征矩阵

corpus=['second third document.','second second document.']  #语料库 ，每一行一个文档

#定义了一个类的实例
#Transform步骤是把X这个计数矩阵转换成tf-idf表示， X = X * self._idf_diag，然后进行归一化
vectorizer=TfidfVectorizer()  

# Fit步骤学习idf vector，一个全局的词权重_idf_diag。输入的X是一个稀疏矩阵，行是样本数，列是特征数。
X=vectorizer.fit_transform(corpus)

# X : array, [n_samples, n_features]   Document-term matrix.
print(X.toarray())
#[[0.50154891 0.50154891 0.70490949]
    #[0.4472136  0.89442719 0.        ]]

print(X, type(X), X.shape, '\n', X.toarray())
#(0, 0)	0.5015489070943787
#(0, 2)	0.7049094889309326
#(0, 1)	0.5015489070943787
#(1, 0)	0.4472135954999579
#(1, 1)	0.8944271909999159
# 其实还有一行为0，X直接Pass了
#<class 'scipy.sparse.csr.csr_matrix'> ， csr_matrix矩阵 = tuple_indx坐标位置信息(橫坐标，indices纵坐标), value值
#(2, 3) 
#[[0.50154891 0.50154891 0.70490949]
    #[0.4472136  0.89442719 0.        ]]

# X 是一个2行3列的矩阵，X[0]也是一个csr_matrix矩阵一部分
print(X[0])
print(X.getrow(0).indices)
#[0 2 1], 这个indies是列的index
print(X.getrow(0).data) 
#[0.50154891 0.70490949 0.50154891] ，这是每列对应的vectory

# TfidfVectorizer从训练数据集中学习到词典vocab=['document', 'second', 'third']包含三个词，
# 并且学习到_idf的全局idf vector
print(vectorizer.get_feature_names()) 
# ['document', 'second', 'third']


######


# 全局item
print(vectorizer.vocabulary_.items())
#dict_items([('second', 1), ('third', 2), ('document', 0)]) 一个list


voc = dict((i, w) for w, i in vectorizer.vocabulary_.items())
print(voc)#用个字典存储一下, 序号代表每一列
#{1: 'second', 2: 'third', 0: 'document'}

test=['a first second document.','thid ac dc.']
print(vectorizer.transform(test).toarray())
#来了新的测试样本，会生成document-term矩阵，矩阵中的数是该文档中该词出现的次数，即tf;然后tf*idf（从idf vector中查找），
# 最后归一化。因此第二个测试样本都为0
# text1 = np.array([1.0, 2.0, 0,0,0,0])
# a / 平方根(a平方+b平方)
# (1.0/np.sqrt(math.pow(1.0,2)+math.pow(2.0,2)))*text1

#[[0.70710678 0.70710678 0.        ]
    #[0.         0.         0.        ]]

print(vectorizer.get_feature_names()) 
#['document', 'second', 'third']

#inverse_transform(X)：返回某篇训练文档向量中的非0特征值所对应的特征词列表
print(vectorizer.inverse_transform(vectorizer.transform(test)))
#[array(['second', 'document'], dtype='<U8'), array([], dtype='<U8')]

sh_list = []
print(X.shape)
#(2, 3)

from simhash import Simhash
# X.shape[0] = 2
for i in range(X.shape[0]):
    Xi = X.getrow(i) # 根据行号，获取每一行
    print(Xi.indices) # 每一行的每一列序号集合
    print(Xi.data) # 每一行的每一列数据data
    # vec #{1: 'second', 2: 'third', 0: 'document'}
    #features表示 (token单词, weight vectory向量)元祖形式的列表
    features = zip([voc[j] for j in Xi.indices], Xi.data)

    # 根据simhash计算hash值
    sh_list.append(Simhash(features))
print(sh_list)

#Simhash具有distance属性
distince = sh_list[0].distance(sh_list[1])
print()#计算一下距离相似度

value = 5
print("海明距离：", distince, "判定距离：", value, "是否相似：", distince<=value)